home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-12-31 | 80.4 KB | 2,076 lines | [TEXT/R*ch] |
- Received-Date: Thu, 8 Sep 1994 18:50:22 +0200
- From: pottier@clipper.ens.fr (Francois Pottier)
- Subject: csmp-digest-v3-055
- To: csmp-digest@ens.fr
- Date: Thu, 8 Sep 1994 18:50:13 +0200 (MET DST)
- X-Mailer: ELM [version 2.4 PL23]
- Mime-Version: 1.0
- Content-Type: text/plain; charset=ISO-8859-1
- Content-Transfer-Encoding: 8bit
- Errors-To: listman@ens.fr
- Reply-To: pottier@clipper.ens.fr
- X-Sequence: 60
-
- C.S.M.P. Digest Thu, 08 Sep 94 Volume 3 : Issue 55
-
- Today's Topics:
-
- Clover+. interrupt?~
- Standard C Libraries: use them?
- Summary of 'Safe Save' problem - IM:Files flawed!
- What Happens in the Resource Fork
- Why does NewGWorld do this?
- Won't strange windows come in my layer?
-
-
-
- The Comp.Sys.Mac.Programmer Digest is moderated by Francois Pottier
- (pottier@clipper.ens.fr).
-
- The digest is a collection of article threads from the internet newsgroup
- comp.sys.mac.programmer. It is designed for people who read c.s.m.p. semi-
- regularly and want an archive of the discussions. If you don't know what a
- newsgroup is, you probably don't have access to it. Ask your systems
- administrator(s) for details. If you don't have access to news, you may
- still be able to post messages to the group by using a mail server like
- anon.penet.fi (mail help@anon.penet.fi for more information).
-
- Each issue of the digest contains one or more sets of articles (called
- threads), with each set corresponding to a 'discussion' of a particular
- subject. The articles are not edited; all articles included in this digest
- are in their original posted form (as received by our news server at
- nef.ens.fr). Article threads are not added to the digest until the last
- article added to the thread is at least two weeks old (this is to ensure that
- the thread is dead before adding it to the digest). Article threads that
- consist of only one message are generally not included in the digest.
-
- The digest is officially distributed by two means, by email and ftp.
-
- If you want to receive the digest by mail, send email to listserv@ens.fr
- with no subject and one of the following commands as body:
- help Sends you a summary of commands
- subscribe csmp-digest Your Name Adds you to the mailing list
- signoff csmp-digest Removes you from the list
- Once you have subscribed, you will automatically receive each new
- issue as it is created.
-
- The official ftp info is //ftp.dartmouth.edu/pub/csmp-digest.
- Questions related to the ftp site should be directed to
- scott.silver@dartmouth.edu. Currently no previous volumes of the CSMP
- digest are available there.
-
- Also, the digests are available to WAIS users. To search back issues
- with WAIS, use comp.sys.mac.programmer.src. With Mosaic, use
- http://www.wais.com/wais-dbs/comp.sys.mac.programmer.html.
-
-
- -------------------------------------------------------
-
- >From arthur_babitz@mentorg.com (Arthur Babitz)
- Subject: Clover+. interrupt?
- Date: Tue, 23 Aug 1994 13:51:08 -0800
- Organization: Mentor Graphics Corp., Wilsonville, OR., USA
-
- I've been trying unsuccessfully to implement a "clover+." interrupt for a
- compute intensive part of an application. I won't bore you with a list of
- things I've tried which don't work, but can someone point me in the right
- direction? Seems like there must be a standard, simple solution to this
- problem.
-
- Thanks!
-
- +++++++++++++++++++++++++++
-
- >From timothys@hood.uucp (Timothy Sherburne)
- Date: 24 Aug 94 16:19:46 GMT
- Organization: University of Portland
-
- arthur_babitz@mentorg.com (Arthur Babitz) writes:
-
- >I've been trying unsuccessfully to implement a "clover+." interrupt for a
- >compute intensive part of an application. I won't bore you with a list of
- >things I've tried which don't work, but can someone point me in the right
- >direction? Seems like there must be a standard, simple solution to this
- >problem.
-
- >Thanks!
-
- The trick is to check for a cmd-. (the "clover" key is usually called the command key) in your event loop. Or you could implement a GetKeys filter.
-
- Here's a snippet using WaitNextEvent that returns a "true" if cmd-. is detected:
-
- Boolean CheckForCmdPeriod (void)
- {
- EventRecord theEvent;
- char key;
- Boolean result = false;
-
- // Wait for an event...
-
- if (WaitNextEvent (keyDownMask, &theEvent, kMaxSleep, nil))
- {
- // Get the ASCII value of the key from the event record...
-
- key = theEvent.message & charCodeMask;
-
- // If the key value is equal to that of the period key and
- // the command modifier key is also being held down, then
- // set result to true...
-
- if ((theEvent.modifiers & cmdKey) && key == '.') // cmd-.
- result = true;
- }
-
- return result;
- }
-
- Here's a snippet using the "GetKeys" toolbox call:
-
- Boolean CheckForCmdPeriod (void)
- {
- KeyMap keys;
-
- // Check to see if the user has pressed command-period keys...
-
- GetKeys (keys);
- if(keys [1] & 0x00800000) // command
- {
- GetKeys (keys);
- if(keys[1] & 0x00008000) // . (period)
- {
- FlushEvents (mDownMask + mUpMask, 0);
- return true;
- }
- }
- else
- return false;
- }
-
- The GetKeys call will catch cmd-. that is intended for anyone, so use it sparingly. It will also not filter the cmd-.
-
-
-
- Don't Panic,
-
-
- t
- --
- | Timothy Sherburne | Software Engineer |
- | Internet: timothys@uofport.edu | Prometheus Products, Inc. |
- | AppleLink: D6164@applelink.apple.com | 1-800-477-3473 |
- *All comments are my own and in no way represent those of Prometheus Products*
-
- +++++++++++++++++++++++++++
-
- >From dshayer@netcom.com (David Shayer)
- Date: Wed, 24 Aug 1994 18:04:50 GMT
- Organization: NETCOM On-line Communication Services (408 261-4700 guest)
-
- Arthur Babitz (arthur_babitz@mentorg.com) wrote:
- : I've been trying unsuccessfully to implement a "clover+." interrupt for a
- : compute intensive part of an application. I won't bore you with a list of
- : things I've tried which don't work, but can someone point me in the right
- : direction? Seems like there must be a standard, simple solution to this
- : problem.
-
- The simplest solution is to simply call WaitNextEvent every so often,
- checking for keydown events of cmd-period. This is polling, not
- interrupt based. But that's the correct way to do it on a Mac.
-
- David
-
-
- +++++++++++++++++++++++++++
-
- >From rhn@waltz.engr.sgi.com (Ron Nicholson)
- Date: Thu, 25 Aug 1994 02:02:12 GMT
- Organization: Silicon Graphics, Inc., Mountain View, CA
-
- In article <timothys.777745186@hood>,
- Timothy Sherburne <timothys@hood.uucp> wrote:
- >arthur_babitz@mentorg.com (Arthur Babitz) writes:
- >
- >>I've been trying unsuccessfully to implement a "clover+." interrupt for a
- >>compute intensive part of an application. I won't bore you with a list of
- >>things I've tried which don't work, but can someone point me in the right
- >>direction? Seems like there must be a standard, simple solution to this
- >>problem.
- (snip)
- >Here's a snippet using WaitNextEvent that returns a "true" if cmd-. ...
- >
- (snip)
-
- A program has to call WaitNextEvent to cleanly check for a keyboard
- abort (command-period). I tried this in an inner loop of a compute
- intensive application and it slowed down the computation noticeably.
- I had to figure out a way to poll often enough to not make the user
- interface seem sluggish, while slowing calculation down minimally.
-
- What I now do is to is this:
-
- First I install a VBL task whose only function is to increment a global
- variable. That gives me a tickcount variable that can be read without
- a function call. You can also use the TickCount() access function.
- (Or you can just use the lowmem global Ticks at $016A if you aren't
- strictly following Apple's guidelines. Would I do that? :-)
-
- In my inner loop I have code similar to: /* in pseudo code */
-
- int ComputeIntensiveFunction(parameters ...)
- {
- ...
- volatile long int *myTickCountPtr;
- long int CheckNow;
- int LocalCounter; /* a local variable */
-
- myTickCountPtr = &some_tickcount_global; /* point at tickcount */
- CheckNow = *myTickCountPtr + 6; /* every 10th of a second */
- LocalCounter = 25;
- ...
-
- for (i=1,i<1000000000;i++) {
-
- ... /* compute intensive inner loop stuff that goes on forever */
-
- if (--LocalCounter <= 0) {
- if (*myTickCountPtr >= CheckNow) {
- flag = CheckForAbortEvent(); /* wrapper for WaitNextEvent */
- if (flag)
- return(kSomeErrorCode); /* abort calculation */
- /* or alternatively just break */
- else
- CheckNow = *myTickCountPtr + 6;
- }
- LocalCounter = 25; /* or some such value */
- }
- }
- ...
- return(kFinishedCalculating);
- }
-
- Every time through the loop, the code does one local variable decrement
- and compare. Every 25th time, the code does one global variable
- (probably uncached and thus slower) load and compare. Every 10th of a
- second, the code polls the event queue for abort, application switches, etc.
-
- The "6" and "25" are just example values. You might want to choose the
- initial loop counter value based on application tuning and the processor
- speed of the Mac on which the application is running.
-
- - -
- Ronald H. Nicholson, Jr. rhn@engr.sgi.com, rhn@netcom.com, N6YWU
- #include <canonical.disclaimer> // I speak only for myself, etc.
-
- +++++++++++++++++++++++++++
-
- >From radixinc@aol.com (RadixInc)
- Date: 25 Aug 1994 01:11:10 -0400
- Organization: America Online, Inc. (1-800-827-6364)
-
- In article <Cv2Izo.Ao1@odin.corp.sgi.com>, rhn@waltz.engr.sgi.com (Ron
- Nicholson) writes:
-
- <<
- A program has to call WaitNextEvent to cleanly check for a keyboard
- abort (command-period). I tried this in an inner loop of a compute
- intensive application and it slowed down the computation noticeably.
- I had to figure out a way to poll often enough to not make the user
- interface seem sluggish, while slowing calculation down minimally.
- >>
-
- A program has to call WaitNextEvent to cleanly do a lot of things. If you
- aren't checking events you are hogging the machine and not letting other
- apps have time. And what do you mean "not make the user interface seem
- sluggish?" What user interface do you have when you aren't checking for
- events?
-
- <<
- First I install a VBL task whose only function is to increment a global
- variable. That gives me a tickcount variable that can be read without
- a function call. You can also use the TickCount() access function.
- (Or you can just use the lowmem global Ticks at $016A if you aren't
- strictly following Apple's guidelines. Would I do that? :-)
- >>
-
- This is silly. Just call TickCount(), or if you have to, just look at
- Ticks. You are overly worried about performance, yet you install a VBL
- task that does the same thing as an existing VBL task (how do you think
- Ticks gets updated in the first place?). You can use any DOCUMENTED
- low-memory globals, like Ticks, without getting in trouble. Certainly
- given the choice between that and installing a VBL, DTS would advise the
- former.
-
- As for the code sample, why not call EventAvail periodically with an event
- mask that ignores events you don't care about? That way you won't end up
- with an event loop inside your compute-intensive loop and (presumably)
- another one in your main program. (DTS will certainly frown on calling
- WaitNextEvent from more than one place in your program). And rather than
- using Ticks and the local counter, use a modulo calculation on your loop
- variable; e.g. check for an event every 10,000 iterations or so.
-
- Make it work first, optimize the slow parts later [after identifying the
- slow parts].
-
- Gregory Jorgensen
- Radix Consulting Inc.
-
- +++++++++++++++++++++++++++
-
- >From rhn@waltz.engr.sgi.com (Ron Nicholson)
- Date: Thu, 25 Aug 1994 17:31:16 GMT
- Organization: Silicon Graphics, Inc., Mountain View, CA
-
- In article <33h95e$ekn@search01.news.aol.com>,
- RadixInc <radixinc@aol.com> wrote:
- >
- >As for the code sample, why not call EventAvail periodically with an event
- >mask that ignores events you don't care about? That way you won't end up
- >with an event loop inside your compute-intensive loop and (presumably)
- >another one in your main program. (DTS will certainly frown on calling
- >WaitNextEvent from more than one place in your program). And rather than
- >using Ticks and the local counter, use a modulo calculation on your loop
- >variable; e.g. check for an event every 10,000 iterations or so.
- >
-
- You're right, EventAvail is a better choice for polling. But what's
- wrong with calling WNE from more than one place? WNE has an eventmask
- also. I just get the events that I want to abort my loop, allow WNE to
- put the program in the background, etc.
-
- Using a modula on the loop count is very bad. The difference in speed
- between a Plus and a 8100/80 is enormous, especially on FP stuff.
- Either you will poll much to seldom on slow machines. Or waste a lot
- of time in WNE on fast machines. That's assuming that the time through
- the loop is deterministic. If it isn't, the Mac GUI could get jerky
- suddenly if the modulo is set wrong on any machine.
-
- My goal was to poll WNE at the same rate on slow and fast machines so
- that the Mac GUI never feels jerky (menus drop promptly, etc.). Around
- the neighborhood of 15 times a second feels about right. This works
- for me and doesn't slow down a program that spends a lot of time doing
- FFT's more than 1%.
-
- - -
- Ronald H. Nicholson, Jr. rhn@engr.sgi.com, rhn@netcom.com, N6YWU
- #include <canonical.disclaimer> // I speak only for myself, etc.
-
- +++++++++++++++++++++++++++
-
- >From radixinc@aol.com (RadixInc)
- Date: 25 Aug 1994 15:29:10 -0400
- Organization: America Online, Inc. (1-800-827-6364)
-
- I understand that the overhead of making the WNE toolbox call and polling
- for events is time consuming, especially if you are trying to squeeze the
- most performance out of a loop. Lots of programs just put up the "watch"
- cursor and ignore all events while they do their computation. This is
- considered bad etiquette, because WNE does more than just feed events to
- your app. It is the only way to let other processes have time. Those other
- processes may just be apps sitting there waiting for user input, in which
- case it doesn't matter, but they may be important background processes,
- such as network software or background printing.
-
- Because so many programs are rude about giving up time with WNE, some
- developers have gone the route of installing VBL or Time Manager tasks to
- make sure they get time, and this is even worse.
-
- If your method of calling WNE every 10 ticks works, and you can live with
- the potential problems of having two WNE calls in your program, great. I
- still think you'd be better off calling EventAvail with an event mask, so
- if an event does show up you can exit your loop and let your "main" even
- loop handle the event (EventAvail doesn't dequeue the event). You can use
- a mask to just look for keyboard events, so mouse events and so on are
- ignored (but remain in the even queue).
-
- Also keep in mind that, depending on the speed of the Mac you are running
- on, events don't live all that long. The event queue only holds 20 events,
- and if you aren't removing them with WNE the old events will be lost. That
- means you have to poll for events fast enough to catch them before they
- are lost. User-interface events will happen much less frequently than
- every 10 ticks, but network events may happen very fast on certain Macs.
-
-
- Gregory Jorgensen
- Radix Consulting Inc.
-
- +++++++++++++++++++++++++++
-
- >From wilkins@jarthur.cs.hmc.edu (Mark Wilkins)
- Date: 25 Aug 1994 21:03:07 GMT
- Organization: Harvey Mudd College, Claremont CA
-
- In article <33ire6$s4i@search01.news.aol.com>,
- RadixInc <radixinc@aol.com> wrote:
- >If your method of calling WNE every 10 ticks works, and you can live with
- >the potential problems of having two WNE calls in your program, great. I
- >still think you'd be better off calling EventAvail with an event mask...
-
-
- What possible problems could be caused by having multiple calls to
- WaitNextEvent in an application, especially if the purpose is to check for
- interruption of a time-consuming process?
-
- An application which doesn't try to do nifty things like threading will
- usually limit user input during a time-consuming processing task to that
- which could interrupt the task or that which needs to be passed on to the OS
- such as a click in another app's window.
-
- In other words, why should I care if I'm throwing away events which don't
- consist of a command period or mouse click when those are the only two forms
- of interaction my application will entertain when it's chugging away? That
- is, assuming I'm only throwing away events directed at my application...
-
- I'm just not sure I see the issue.
-
- -- Mark Wilkins
-
- +++++++++++++++++++++++++++
-
- >From radixinc@aol.com (RadixInc)
- Date: 26 Aug 1994 00:11:08 -0400
- Organization: America Online, Inc. (1-800-827-6364)
-
- In article <33j0ub$eip@jaws.cs.hmc.edu>, wilkins@jarthur.cs.hmc.edu (Mark
- Wilkins) writes:
-
- <<What possible problems could be caused by having multiple calls to
- WaitNextEvent in an application, especially if the purpose is to check for
- interruption of a time-consuming process? ... In other words, why should I
- care if I'm throwing away events which don't consist of a command period
- or mouse click when those are the only two forms of interaction my
- application will entertain when it's chugging away? That is, assuming I'm
- only throwing away events directed at my application...>>
-
- It's mostly a matter of style, and of course it is generic Mac programming
- advice to have only one place in your code call WNE. It sounds like you
- know what you are doing, and perhaps this is the best way to handle it.
- The complication of calling WNE from more than one place is that you have
- to (or at least should) handle ALL events you get. In your case you are
- going to ignore all events except the ones that can terminate your loop.
- It's most important that you call WNE periodically (and often), for the
- reasons mentioned in my previous post, even if you don't handle all of the
- events.
-
- Besides the key and mouse events, there are other events you may get. You
- can't really get switched out if you ignore mouse clicks outside of your
- window, but another process could do something that causes an update event
- in one of your windows. Or a high-level event could get passed to you (if
- your program accepts them). If you call WNE but can't respond to these
- events in your computation loop, your window won't be updated and you
- won't be able to process Apple Events. In your case maybe this is not a
- big deal.
-
- There is no "hard" reason to have only one WNE call in your program, as
- long as you know that you may lose events.
-
- Gregory Jorgensen
- Radix Consulting Inc.
-
- +++++++++++++++++++++++++++
-
- >From kluev@jonathan.srcc.msu.su (Kluev)
- Date: Sun, 28 Aug 94 18:13:09 +0400
- Organization: (none)
-
- In article <33h95e$ekn@search01.news.aol.com>
- radixinc@aol.com (RadixInc) wrote:
-
- > In article <Cv2Izo.Ao1@odin.corp.sgi.com>, rhn@waltz.engr.sgi.com
- (Ron
- > Nicholson) writes:
- > <<
- > First I install a VBL task whose only function is to increment a
- global
- > variable. That gives me a tickcount variable that can be read
- without
- > a function call. You can also use the TickCount() access function.
- > (Or you can just use the lowmem global Ticks at $016A if you aren't
- > strictly following Apple's guidelines. Would I do that? :-)
- > >>
- > This is silly. Just call TickCount(), or if you have to, just look at
- > Ticks. You are overly worried about performance, yet you install a
- VBL
- > task that does the same thing as an existing VBL task (how do you
- think
- > Ticks gets updated in the first place?).
-
- First: There is no special VBL task that increments Ticks.
- Second: Installing VBLTask that increments global variable gives you
- much less accuracy than looking into Ticks (TickCount). This inaccuracy
- will heavily depend on machine load and may rise up to several "real"
- ticks against one "your" tick. Ticks is guaranteed to be incremented
- every tick, but your VBLTask (which contains 1 in vblCount) is not
- guaranteed to be called every tick.
-
- > WaitNextEvent from more than one place in your program). And rather
- than
- > using Ticks and the local counter, use a modulo calculation on your
- loop
- > variable; e.g. check for an event every 10,000 iterations or so.
-
- This is bad practice. If "10,000" is hard-coded you will get different
- response time on different machines. It may be computed at start-time.
- But think: machine load (VBLs for example) may vary during program
- execution. Processor cache may be turned on/off. All this and more
- will invalidate this "10,000" estimate. Ticks is better.
-
- Michael Kluev.
-
- +++++++++++++++++++++++++++
-
- >From radixinc@aol.com (RadixInc)
- Date: 29 Aug 1994 02:13:04 -0400
- Organization: America Online, Inc. (1-800-827-6364)
-
- In article <584486046668@jonathan.srcc.msu.su>, kluev@jonathan.srcc.msu.su
- (Kluev) writes:
-
- <<First: There is no special VBL task that increments Ticks.>>
-
- Not on newer Macs, no. Ticks used to get updated by a VBL task, but now it
- is synthesized. It doesn't matter how it gets updated; the point is that
- it is better to get the value of Ticks, either by function call or reading
- the global directly. If you use the Universal Headers you can read the
- Ticks global and stay compatible by using LMGetTicks(). For historical
- reasons it's easier to pretend that Ticks is incremented at VBL time, even
- though on most Macs it isn't actually done that way. I apologize if anyone
- was confused or misled by my statement, but it really makes no difference
- how Ticks gets incremented, and by design it appears that it is done at
- VBL time.
-
- <<This is bad practice. If "10,000" is hard-coded you will get different
- response time on different machines.>>
-
- Obviously, but you are misreading my message. I wasn't suggesting
- hard-coding the number 10,000, or any other number--I was suggesting a
- modulo calculation based on SOME modulus. The actual number used could be
- any value, and could be calculated in advance to account for differences
- among machines. 10,000 was simply an illustrative example, and that's why
- I wrote "e.g. check for an event every 10,000 iterations or so." "e.g."
- is an abbrevation for "exempli gratia," meaning "for example," not to be
- confused with "i.e.," (id est), meaning "that is." This should be
- self-evident to anyone capable of writing a VBL task in the first place,
- and therefore I didn't see any reason to exhaustively explain what I was
- suggesting. Quod erat demonstrandum.
-
- <<But think: machine load (VBLs for example) may vary during program
- execution. Processor cache may be turned on/off. All this and more
- will invalidate this "10,000" estimate. Ticks is better.>>
-
- I agree, but the original post, and my response, were discussing other
- approaches. My suggestion, which was followed up by email, was to simply
- read the value of Ticks and be done with it. Done correctly the modulus
- method is a legitimate way to handle the problem, if for some reason the
- programmer doesn't want to use Ticks.
-
- Gregory Jorgensen
- Radix Consulting Inc.
-
- +++++++++++++++++++++++++++
-
- >From besbris@jeeves.ucsd.edu (David Besbris)
- Date: 29 Aug 1994 10:25:39 GMT
- Organization: The Avant-Garde of the Now, Ltd.
-
- Kluev (kluev@jonathan.srcc.msu.su) wrote:
- (snip)
-
- : First: There is no special VBL task that increments Ticks.
- : Second: Installing VBLTask that increments global variable gives you
- : much less accuracy than looking into Ticks (TickCount). This inaccuracy
- : will heavily depend on machine load and may rise up to several "real"
- : ticks against one "your" tick. Ticks is guaranteed to be incremented
- : every tick, but your VBLTask (which contains 1 in vblCount) is not
- : guaranteed to be called every tick.
-
- (snip)
-
- : This is bad practice. If "10,000" is hard-coded you will get different
- : response time on different machines. It may be computed at start-time.
- : But think: machine load (VBLs for example) may vary during program
- : execution. Processor cache may be turned on/off. All this and more
- : will invalidate this "10,000" estimate. Ticks is better.
-
- : Michael Kluev.
-
- Ticks is INDEED incremented by a system-installed VBL task, and is NOT
- guaranteed to be inceremented exactly once evey tick. (for the reasons that
- you mention about the inaccuracy of using a VBL task.) I'm curious, why do you
- say otherwise?
-
-
- -Dave
-
- One of the last Mac Pascal programmers...
-
- besbris@jeeves.ucsd.edu
-
-
- +++++++++++++++++++++++++++
-
- >From kluev@jonathan.srcc.msu.su (Kluev)
- Date: Tue, 30 Aug 94 16:42:18 +0400
- Organization: (none)
-
- In article <33sd33$4lh@network.ucsd.edu>
- besbris@jeeves.ucsd.edu (David Besbris) wrote:
-
- > Kluev (kluev@jonathan.srcc.msu.su) wrote:
- > (snip)
- >
- > : First: There is no special VBL task that increments Ticks.
- > : Second: Installing VBLTask that increments global variable gives
- you
- > : much less accuracy than looking into Ticks (TickCount). This
- inaccuracy
- > : will heavily depend on machine load and may rise up to several
- "real"
- > : ticks against one "your" tick. Ticks is guaranteed to be
- incremented
- > : every tick, but your VBLTask (which contains 1 in vblCount) is not
- > : guaranteed to be called every tick.
- >
- > : Michael Kluev.
- >
- > Ticks is INDEED incremented by a system-installed VBL task, and is
- NOT
- > guaranteed to be inceremented exactly once evey tick. (for the
- reasons that
- > you mention about the inaccuracy of using a VBL task.) I'm curious,
- why do
- > you say otherwise?
- >
- > -Dave
-
- Here's the story on how VBL mechanism work, at least as I understand
- it. Ticks is updated by "VBL mechanism", *not* by system-installed
- VBL task. The first thing that is done by VBL mechanism is incrementing
- Ticks variable. Then it gets sure that it is not already running
- (by looking in VBLQueue). If it is already running, there is nothing
- to do, just return. If it is not running, mechanism decrements
- vblCounts of VBL tasks, and calls those, which have zero in vblCount.
- While VBL task is getting called, VBL mechanism may be entered again.
- (This is another story, how is it getting called: is it real video card
- interrupt, or is it triggered VIA interrupt. For now it is important
- only, that mechanism is getting called every 1/60 sec or so.) In this
- case the only thing it does is incrementing Ticks variable. So Ticks
- *is guaranteed* (if we aren't talking about situations when interrupts
- are disabled for a long time, e. g. diskette formatting) to be
- incremented every tick, but VBL task that has 1 in vblCount
- *is not guaranteed* to be called every tick. As far as I know all
- Macs since 1984 share this scheme.
-
- If you don't believe me, disassemble a few bytes of ROM above the
- code that calls your VBL task (on my machine it starts at
- "_VRemove+16".
- You will see:
-
- +0014 RTS
- ; Starting point of "VBL mechanics"
- +0016 ADDQ.L #$1, Ticks; increments Ticks global
- +001A .....
- +0020 BSET #$06, VBLQueue; test if it is already running
- +0026 BNE _VRemove+0014; nothing can do - return.
-
- If you still don't believe me, write a small test. Install VBL task
- that does the following:
- ...
- Task-> vblCount = 1; // reinstalls itself
- MyTicks++; // increments global
- Delay(10, &L); // degrades machine performance,
- // (emulates Mac Plus or so)
- // You may try to use this "for" loop instead of Delay
- // for (i = 0; i < 1000000L; i++);
- ...
-
- In your main write:
- ...
- VInstall(...); // installs VBL task with 1 in vblCount
- MyOldTicks = MyTicks; // saves old timers
- OldTicks = TickCount();
- Delay(60*10); // waits 10 seconds
- MyNewTicks = MyTicks;
- NewTicks = TickCount(); // gets new timers
-
- NumToString(MyNewTicks - MyOldTicks, String);
- DebugStr(String);
- NumToString(NewTicks - OldTicks, String);
- DebugStr(String); // makes things obvious
-
- ...You will notice a big difference.
-
- As someone else pointed, for more exact and/or long-term measurements
- it is better to use other mechanisms instead of Ticks (e. g. Time
- Manager or GetDateTime).
-
- Michael Kluev.
-
- +++++++++++++++++++++++++++
-
- >From kluev@jonathan.srcc.msu.su (Kluev)
- Date: Fri, 2 Sep 94 21:33:30 +0400
- Organization: (none)
-
- In article <33ire6$s4i@search01.news.aol.com>
- radixinc@aol.com (RadixInc) wrote:
-
- > I understand that the overhead of making the WNE toolbox call and
- polling
- > for events is time consuming, especially if you are trying to squeeze
- the
- > most performance out of a loop. Lots of programs just put up the
- "watch"
- > cursor and ignore all events while they do their computation. This is
- > considered bad etiquette, because WNE does more than just feed events
- to
- > your app. It is the only way to let other processes have time.
-
- EventAvail and GetNextEvent also allow other processes to work. Their
- "time consuming" is approximately the same as of WaitNextEvent.
-
- > Also keep in mind that, depending on the speed of the Mac you are
- running
- > on, events don't live all that long. The event queue only holds 20
- events,
- > and if you aren't removing them with WNE the old events will be lost.
- That
- > means you have to poll for events fast enough to catch them before
- they
- > are lost. User-interface events will happen much less frequently than
- > every 10 ticks, but network events may happen very fast on certain
- Macs.
-
- Do you use those cool "network" events? This is not recommended
- practice.
-
- Michael Kluev.
-
- +++++++++++++++++++++++++++
-
- >From radixinc@aol.com (RadixInc)
- Date: 25 Aug 1994 01:11:10 -0400
- Organization: America Online, Inc. (1-800-827-6364)
-
- In article <Cv2Izo.Ao1@odin.corp.sgi.com>, rhn@waltz.engr.sgi.com (Ron
- Nicholson) writes:
-
- <<
- A program has to call WaitNextEvent to cleanly check for a keyboard
- abort (command-period). I tried this in an inner loop of a compute
- intensive application and it slowed down the computation noticeably.
- I had to figure out a way to poll often enough to not make the user
- interface seem sluggish, while slowing calculation down minimally.
- >>
-
- A program has to call WaitNextEvent to cleanly do a lot of things. If you
- aren't checking events you are hogging the machine and not letting other
- apps have time. And what do you mean "not make the user interface seem
- sluggish?" What user interface do you have when you aren't checking for
- events?
-
- <<
- First I install a VBL task whose only function is to increment a global
- variable. That gives me a tickcount variable that can be read without
- a function call. You can also use the TickCount() access function.
- (Or you can just use the lowmem global Ticks at $016A if you aren't
- strictly following Apple's guidelines. Would I do that? :-)
- >>
-
- This is silly. Just call TickCount(), or if you have to, just look at
- Ticks. You are overly worried about performance, yet you install a VBL
- task that does the same thing as an existing VBL task (how do you think
- Ticks gets updated in the first place?). You can use any DOCUMENTED
- low-memory globals, like Ticks, without getting in trouble. Certainly
- given the choice between that and installing a VBL, DTS would advise the
- former.
-
- As for the code sample, why not call EventAvail periodically with an event
- mask that ignores events you don't care about? That way you won't end up
- with an event loop inside your compute-intensive loop and (presumably)
- another one in your main program. (DTS will certainly frown on calling
- WaitNextEvent from more than one place in your program). And rather than
- using Ticks and the local counter, use a modulo calculation on your loop
- variable; e.g. check for an event every 10,000 iterations or so.
-
- Make it work first, optimize the slow parts later [after identifying the
- slow parts].
-
- Gregory Jorgensen
- Radix Consulting Inc.
-
- ---------------------------
-
- >From dlopez@sailsun (Dean Lopez)
- Subject: Standard C Libraries: use them?
- Date: 12 Aug 1994 18:46:29 GMT
- Organization: NASA Johnson Space Center, Houston, TX, USA
-
- I am wondering about the 'legitimacy' of using the Standard C Libraries
- in my Mac applications. As a C programmer on other systems, I've become
- quite fond of the Standard C libraries - stdio.h in particular. The
- problem with using them on the Mac, as I'm sure you all know, is the way
- files are reference via FILE* 'ers compared with the File Manager's
- file reference numbers. If I use the File Manager, I don't see how I
- can use the stdio.h functions which require a FILE*. And if I use the
- stdio.h functions, I can't use some of the File Manager's goodies.
-
- Has anybody figured out how to convert the FILE structure info into the
- FSSpec structure? (I mean written the routines already, I really don't
- have the time right now to attempt it myself).
- I'd just like to be able to interchange how I reference a file right
- now, in the same way on say, a Data General system using AOS will let
- me reference a file either with the stdio or Unix calls.
-
- Is there a reason NOT to try to use either/or?
-
- Any and all advice welcome. NOTE: if you e-mail me, see my email addresses
- below, don't use what's in my reply-to field. Its messed up somehow.
- --
- +---------------------------------------+-----------------------------+
- | Dean Lopez | |
- | SAIL DPS Engineer | dlopez@sailsun.jsc.nasa.gov |
- | Rockwell Space Operations Co. | deanlopez@aol.com |
- | JSC Shuttle Avionics Integration Lab | dean_lopez@maclair.cld9.com |
- +---------------------------------------+-----------------------------+
- #include <standard_disclaimer.h>
- /* The opinions expressed are all mine.
- RSOC doesn't speak for me and I don't speak for RSOC
- After all, I'm only an engineer - what do I know? */
-
- +++++++++++++++++++++++++++
-
- >From rollin@newton.apple.com (Keith Rollin)
- Date: Thu, 18 Aug 1994 04:26:36 -0800
- Organization: Apple ][ -> Mac -> Taligent -> Newton -> Windows?
-
- In article <32gg25$of9@pendragon.jsc.nasa.gov>, dlopez@sailsun (Dean
- Lopez) wrote:
-
- >I am wondering about the 'legitimacy' of using the Standard C Libraries
- >in my Mac applications. As a C programmer on other systems, I've become
- >quite fond of the Standard C libraries - stdio.h in particular. The
- >problem with using them on the Mac, as I'm sure you all know, is the way
- >files are reference via FILE* 'ers compared with the File Manager's
- >file reference numbers. If I use the File Manager, I don't see how I
- >can use the stdio.h functions which require a FILE*. And if I use the
- >stdio.h functions, I can't use some of the File Manager's goodies.
- >
- >Has anybody figured out how to convert the FILE structure info into the
- >FSSpec structure? (I mean written the routines already, I really don't
- >have the time right now to attempt it myself).
- >I'd just like to be able to interchange how I reference a file right
- >now, in the same way on say, a Data General system using AOS will let
- >me reference a file either with the stdio or Unix calls.
- >
- >Is there a reason NOT to try to use either/or?
-
- Check the Mac Technotes:
-
- "Frequently, developers want to use both Macintosh file I/O and C file
- I/O. Developers who do this must keep in mind that they are combining two
- distinct file representations (the Macintosh and ANSI C). The only
- limitation on mixing HFS and C I/O functions is that they cannot be mixed
- on the same open file. There are three reasons why this cannot be done.
-
- "First, there is no routine that maps between a C FILE struct (returned by
- fopen()) to an HFS fRefNum (needed to call HFS functions). Similarly,
- there is no call to create a FILE struct given an fRefNum returned by
- FSOpen(). Thus, there is no way that the information from an fopen() call
- could be used to do a FSRead().
-
- "Second, even if the first problem were solved, the C libraries eventually
- call the HFS file system, but keep some internal state information. So,
- if you call HFS directly (say, SetFPos()), the C file system has no way of
- knowing a call was made and, therefore, doesnπt update its state
- information.
-
- "Similarly, there is no mechanism for synchronizing the C libraryπs
- buffers. For example, you perform an fwrite() with some number of
- characters which get put into a buffer without flushing it. Then you
- perform an FSWrite() with something else. Neither the C library nor HFS
- are aware that the other has written to the file.
-
- "Simply put, you cannot make HFS calls on a file opened with fopen() or
- fdopen(); you cannot use C library I/O on a file opened under HFS."
-
- - --------------------------------------------------------------------------
- Keith Rollin --- Phantom Programmer --- Apple Computer, Inc. --- Team Newton
-
- +++++++++++++++++++++++++++
-
- >From cjsmith@nwu.edu (Jeremy Smith)
- Date: 18 Aug 1994 15:37:49 GMT
- Organization: Northwestern University, Evanston, IL USA
-
- I'm not sure, what exactly you're trying to do, but if you have a copy
- of Think Reference, go to misc. topics/Code Example Orphans/Printing a
- Text File and look at the GotATextFile procedure. This uses a medly of
- toolbox and ANSI file routines. Good luck,
-
- Jeremy Smith
- cjsmith@nwu.edu
-
- +++++++++++++++++++++++++++
-
- >From phils@bedford.symantec.com (Phil Shapiro)
- Date: Mon, 22 Aug 1994 14:37:27 -0400
- Organization: Symantec Corp.
-
- In article <rollin-1808940426360001@mac691.kip.apple.com>,
- rollin@newton.apple.com (Keith Rollin) wrote:
-
- | In article <32gg25$of9@pendragon.jsc.nasa.gov>, dlopez@sailsun (Dean
- | Lopez) wrote:
- |
- | >I am wondering about the 'legitimacy' of using the Standard C Libraries
- | >in my Mac applications. As a C programmer on other systems, I've become
- | >quite fond of the Standard C libraries - stdio.h in particular. The
- | >problem with using them on the Mac, as I'm sure you all know, is the way
- | >files are reference via FILE* 'ers compared with the File Manager's
- | >file reference numbers. If I use the File Manager, I don't see how I
- | >can use the stdio.h functions which require a FILE*. And if I use the
- | >stdio.h functions, I can't use some of the File Manager's goodies.
- | >
- | >Is there a reason NOT to try to use either/or?
- |
- | Check the Mac Technotes:
- |
- | "First, there is no routine that maps between a C FILE struct (returned by
- | fopen()) to an HFS fRefNum (needed to call HFS functions). Similarly,
- | there is no call to create a FILE struct given an fRefNum returned by
- | FSOpen(). Thus, there is no way that the information from an fopen() call
- | could be used to do a FSRead().
-
- The Mac Technotes have always assumed that everyone is using the MPW
- development system. If you're using THINK, you *can* get the refnum for an
- open FILE. It's stored in the field called "refnum". You could also write
- a stdio routine that builds a FILE* from an open file, since the THINK
- libraries ship with full source. But that's a fair amount of work just
- because you happen to like ANSI I/O. You will only be able to use the code
- in THINK, too.
-
- Unless you're porting a lot of code that already uses ANSI I/O, you're
- much better off going with straight Mac I/O.
-
- -phil
-
- +++++++++++++++++++++++++++
-
- >From nagle@netcom.com (John Nagle)
- Date: Tue, 23 Aug 1994 02:02:25 GMT
- Organization: NETCOM On-line Communication Services (408 261-4700 guest)
-
- phils@bedford.symantec.com (Phil Shapiro) writes:
- >In article <rollin-1808940426360001@mac691.kip.apple.com>,
- >rollin@newton.apple.com (Keith Rollin) wrote:
- >| In article <32gg25$of9@pendragon.jsc.nasa.gov>, dlopez@sailsun (Dean
- >| Lopez) wrote:
- >| >I am wondering about the 'legitimacy' of using the Standard C Libraries
- >| >in my Mac applications. As a C programmer on other systems, I've become
- >| >quite fond of the Standard C libraries - stdio.h in particular.
-
- >The Mac Technotes have always assumed that everyone is using the MPW
- >development system. If you're using THINK, you *can* get the refnum for an
- >open FILE.
-
- >Unless you're porting a lot of code that already uses ANSI I/O, you're
- >much better off going with straight Mac I/O.
-
- Of course, then you have to try to read a text file with the
- Toolbox calls, a difficult, slow, and badly documented operation.
- Anybody have the obscure tech note reference on doing that?
-
- John Nagle
-
- +++++++++++++++++++++++++++
-
- >From zstern@adobe.com (Zalman Stern)
- Date: Tue, 23 Aug 1994 05:51:49 GMT
- Organization: Adobe Systems Incorporated
-
- That the Mac API prevents the use of stdio in many cases is just a bug. Any
- reasonable UNIX system provides functions to map a FILE * to a file
- descriptor (the moral equivalent of a Mac file reference number) and to open
- a FILE * from a file descriptor. (They're called fileno and fdopen
- respectively.) The conventions for switching between system call level I/O
- and stdio are a bit arcane but workable for most uses of this functionality.
- (The fdopen call is necessary because UNIX has a unified model of stream I/O
- which a large number of things obey. There are many ways to get a file
- descriptor, but once you have one it behaves according to this model and
- turning it into a stdio stream is very useful.)
-
- I've seen a number of posts recently that express the attitude that there is
- no point in using portable API's for Macintosh programming because Mac
- applications are inherently non-portable. (Or perhaps these posters feel a
- program isn't a good Macintosh application unless its non-portable.) People
- who feel this way are quickly becoming economic roadkill, and deservedly so.
- One writes non-portable code because less than ideal circumstances forces
- one to, not because it is desirable.
- --
- Zalman Stern zalman@adobe.com (415) 962 3824
- Adobe Systems, 1585 Charleston Rd., POB 7900, Mountain View, CA 94039-7900
- Please do not change color while I am talking to you -- MC 900 Ft Jesus.
-
- +++++++++++++++++++++++++++
-
- >From tree@bedford.symantec.com (Tom Emerson)
- Date: Tue, 23 Aug 1994 06:33:54 -0500
- Organization: Symantec Development Tools Group
-
- > >Unless you're porting a lot of code that already uses ANSI I/O, you're
- > >much better off going with straight Mac I/O.
- >
- > Of course, then you have to try to read a text file with the
- > Toolbox calls, a difficult, slow, and badly documented operation.
- > Anybody have the obscure tech note reference on doing that?
-
- IM: Files, p. 2-90 & 2-122.
-
- -tre
-
- --
- Tom Emerson Software Engineer
- Development Tools Group Symantec Corporation
- tree@bedford.symantec.com
- "I dreamed I had to take a test, in a Dairy Queen, on another planet."
-
- +++++++++++++++++++++++++++
-
- >From quinn@cs.uwa.edu.au (Quinn "The Eskimo!")
- Date: Thu, 25 Aug 1994 11:40:13 +0800
- Organization: Department of Computer Science, The University of Western Australia
-
- In article <1994Aug23.055149.5764@adobe.com>, zstern@adobe.com (Zalman
- Stern) wrote:
-
- >That the Mac API prevents the use of stdio in many cases is just a bug.
-
- I disagree with this. Any API that promotes the use of full paths to
- denote files is fundamentally broken for use on a Mac, mainly because
- multiple volumes can have the same name. Of course you can work around
- this problem but there comes a point where you've got to decide whether
- your workaround is worth the effort.
- --
- Quinn "The Eskimo!" "Scout in a can. Simple, cheap, easy
- to use and it's expendable!"
-
- +++++++++++++++++++++++++++
-
- >From zstern@adobe.com (Zalman Stern)
- Date: Thu, 25 Aug 1994 07:10:14 GMT
- Organization: Adobe Systems Incorporated
-
- Quinn "The Eskimo!" writes
- > In article <1994Aug23.055149.5764@adobe.com>, zstern@adobe.com (Zalman
- > Stern) wrote:
- > >That the Mac API prevents the use of stdio in many cases is just a bug.
- >
- > I disagree with this. Any API that promotes the use of full paths to
- > denote files is fundamentally broken for use on a Mac, mainly because
- > multiple volumes can have the same name. Of course you can work around
- > this problem but there comes a point where you've got to decide whether
- > your workaround is worth the effort.
-
- Fine write a function like so:
-
- FILE * FSfopen(FSSpec *fileSpec, char *mode);
-
- or perhaps a function that pops up a standard file dialog and opens a file
- that way. Then you can write the file processing routines in a portable
- fashion. The other alternative is to write your own stream library and
- ensure that it is portable, but that is fraught with problems. (E.g. the
- MacApp stream implementation which does no buffering.) I prefer not to
- re-invent the wheel unless I have to.
-
- My original point is that with a little work in the stdio implementation one
- can go back and forth easily. My use of "The Mac API" is wrong. I meant the
- standard C library implementation combined with the toolbox requirements.
- Obviously the C library implementation is a better choice to change.
- --
- Zalman Stern zalman@adobe.com (415) 962 3824
- Adobe Systems, 1585 Charleston Rd., POB 7900, Mountain View, CA 94039-7900
- Please do not change color while I am talking to you -- MC 900 Ft Jesus.
-
- ---------------------------
-
- >From redial <redial@netcom.com>
- Subject: Summary of 'Safe Save' problem - IM:Files flawed!
- Date: Thu, 25 Aug 1994 04:29:12 GMT
- Organization: NETCOM On-line Communication Services (408 261-4700 guest)
-
- Netters -
-
- Awhile ago I posted a request for help with a problem I was having
- implementing the 'Safe Save' routine outlined in Inside Macintosh:Files, pp.
- 1-25,26. A 'safe save' is a save routine which creates a temporary file on
- disk, saves the data to it, and - if no error occurs - swaps the the
- directory information for the two files, and then deletes the temporary file.
- The advantage over a 'direct save' to the existing file is that if an error
- were to occur, the existing file could be damaged and its data erased or
- corrupted. The IM example code is in Pascal (naturally), but since I am
- working in C I attempted to translate it to that language. The problem I ran
- into was that after the directory swap between the files, I would get a 'file
- busy' error when I attempted to delete the temporary file. This was quite
- puzzling since the code clearly executes a command to close the temporary
- file immediately before the delete command.
-
- Scott Bronson pointed out that the swap command, FSpExchangeFiles, swaps
- the FCBs too, and recommended closing both files before swapping. However, a
- comment line in the original pascal example directed that the data fork of
- the existing file be opened and left open! I wondered why, but Scott thought
- this was just another example of how inaccurate the code examples in IM can
- be. The bugginess of the 'Safe Save' routine certainly attests to this fact!
-
- Further snooping led to several bits of info about the two files which
- enabled Troy Gaul to correctly diagnose that the IM example code called for a
- resource to be written to the original file BEFORE the swap. Thus, it
- contained the resource and the old data, while the temporary file contained
- only the new data. AFTER the swap, the original file then contained only the
- new data while the temporary file contained the resource and the old data.
- Troy also pointed out that since FSpExchangeFiles also swaps the FCBs if
- either or both files are open, the FSClose routine needs to use the path
- reference number of the _original_ file in order to actually close the
- temporary file! This means that future references to the original file will
- require the use of the temporary file's path refnum, so it must be saved.
-
- Yet another error was discovered by Jens-Uwe Mager. The IM:Files example
- used the FSClose routine to close the resource fork of the original file, but
- this did not cause the resource data to actually be flushed to the disk. He
- correctly suggested the use of CloseResFile, which (contrary to my initial
- response to him) does work exactly like it should.
-
- The first part of the fix is to move the resource creating code from the
- DoSaveAsCmd routine to the DoWriteFile routine. However, you must continue
- to allow the DoSaveAsCmd routine to open the original file's data fork and
- leave it open. This is important because of the interplay between the 'Save'
- and the 'Save As...' file menu commands. The first time the user saves his
- file, the DoSaveAsCmd routine is going to be executed regardless of which
- command was chosen. Thereafter, each time the user selects the 'Save'
- command, the DoSaveAsCmd routine is bypassed and flow goes directly to
- DoWriteData. You could allow DoWriteData to open the original file's data
- fork, but then you'd also have to close it again before leaving the routine.
- Putting just one call to open the data fork in the DoSaveAsCmd is more
- efficient.
-
- The second part of the fix is to make the DoWriteFile routine create the
- temporary file, copy the resource to its resource fork, and close the
- resource fork with CloseResFile. Then the routine should open the temp
- file's data fork, write the current data to it, and leave it open also. Do
- the swap using FSpExchangeFiles. NOW the path reference numbers of the two
- files, which locate their data in memory, are reversed, but their FSSpecs are
- not. Close the temp file by calling FSClose with the _original_ file's path
- reference number. Save the _temporary_ file's path reference number for
- future use with the file, and then delete the temp file by calling FSpDelete
- with the temporary file's FSSpec.
-
- Sorry to be so long winded. If anyone wishes to see the final code, drop me
- an email. And sincere thanks to all who helped.
-
- ===============================================================
- | Ron Goebel | |
- | G & V Systems | Whatdya mean 'I don't get it?' |
- | Internet: redial@netcom.com | |
- ===============================================================
-
- ---------------------------
-
- >From redcon@xmission.com (Dan Eldridge)
- Subject: What Happens in the Resource Fork
- Date: 18 Aug 1994 14:23:26 GMT
- Organization: Redcon
-
- Hi
-
- Here's A general question, that I'm sure someone can answer,
- What happens in the Resource Fork if a program significantly and often
- changes the size of one of the resources, does the fork get fragmented, or
- does the whole file get rewritten so that the forks are all contiguous?
-
-
-
- Just Wondering
-
- --
- Dan
- Redcon
-
- ***
- insert favorite corn dog joke here
- ***
-
- +++++++++++++++++++++++++++
-
- >From mclow@san_marcos.csusm.edu (Marshall Clow)
- Date: Thu, 18 Aug 1994 09:26:20 -0800
- Organization: Aladdin Systems
-
- In article <redcon-1808940824560001@slc17.xmission.com>,
- redcon@xmission.com (Dan Eldridge) wrote:
-
- > Hi
- >
- > Here's A general question, that I'm sure someone can answer,
- > What happens in the Resource Fork if a program significantly and often
- > changes the size of one of the resources, does the fork get fragmented, or
- > does the whole file get rewritten so that the forks are all contiguous?
- >
- My experience has been that if you make resources smaller (or possibly
- delete them), the extra space in the file is left unused, but if you add a
- resource or make one larger, then it is added at the end and the file is
- compacted in UpdateResFile. (which is called from CloseResFile)
-
- -- Marshall
-
- --
- Marshall Clow
- Aladdin Systems
- mclow@san_marcos.csusm.edu
-
- +++++++++++++++++++++++++++
-
- >From Jens Alfke <jens_alfke@powertalk.apple.com>
- Date: Wed, 24 Aug 1994 17:53:54 GMT
- Organization: Apple Computer
-
- Dan Eldridge, redcon@xmission.com writes:
- > What happens in the Resource Fork if a program significantly and often
- > changes the size of one of the resources, does the fork get fragmented, or
- > does the whole file get rewritten so that the forks are all contiguous?
-
- When you call UpdateResFile or CloseResFile, all the data gets shuffled
- around on disk until it's contiguous. Needless to say this can be very slow.
- Remember those long delays you sometimes get when you close the Monitors
- control panel or use some utility to update the desktop pattern? That's the
- cause; the System file is rather large, esp. pre-7.1 systems that had all the
- fonts in the System file itself. And the best part is, if you decide your
- system's hung and reboot, you've just destroyed your system file! That's the
- major reason we made Wallpaper not store its desktop pattern in the System
- file.
-
- All the more reason why (let's all chant it together) "The Resource Manager
- is not a database!"
-
- --Jens Alfke jens_alfke@powertalk.apple.com
- "A man, a plan, a yam, a can of Spam ... Bananama!"
-
- +++++++++++++++++++++++++++
-
- >From kluev@jonathan.srcc.msu.su (Kluev)
- Date: Thu, 25 Aug 94 20:58:39 +0400
- Organization: (none)
-
- In article <1994Aug24.175354.27836@gallant.apple.com>
- Jens Alfke <jens_alfke@powertalk.apple.com> wrote:
-
- > Dan Eldridge, redcon@xmission.com writes:
- > > What happens in the Resource Fork if a program significantly and
- often
- > > changes the size of one of the resources, does the fork get
- fragmented, or
- > > does the whole file get rewritten so that the forks are all
- contiguous?
- >
- > When you call UpdateResFile or CloseResFile, all the data gets
- shuffled
- > around on disk until it's contiguous. Needless to say this can be
- very slow.
-
- This data compacting occurred in "logical" space of fork instead of
- "physical". Compacting removes empty space in fork (not on disk)
- created when a resource was removed, made smaller, or larger.
- "Physically", file can be shuffled around all the disk.
- So the answer is: Yes, the fork get fragmented.
-
- Michael Kluev.
-
- ---------------------------
-
- >From schwarz@kodak.com (Doug Schwarz)
- Subject: Why does NewGWorld do this?
- Date: Tue, 23 Aug 1994 20:07:42 GMT
- Organization: Eastman Kodak Company, Rochester, NY
-
- I am trying to create multiple offscreen graphics worlds.
-
- QDErr err1, err2;
- PixMapHandle pixBase1, pixBase2;
- GWorldPtr theGWorld1, theGWorld2;
- CGrafPtr currentPort;
- GDHandle currentDevice;
- Rect boundsRect;
-
- GetGWorld(¤tPort, ¤tDevice);
- err1 = NewGWorld(&theGWorld1, 32, &boundsRect, NULL, NULL, 0);
- pixBase1 = GetGWorldPixMap(theGWorld1);
- SetGWorld(currentPort, currentDevice);
-
- GetGWorld(¤tPort, ¤tDevice);
- err2 = NewGWorld(&theGWorld2, 32, &boundsRect, NULL, NULL, 0);
- pixBase2 = GetGWorldPixMap(theGWorld2);
- SetGWorld(currentPort, currentDevice);
-
-
- In the code fragment above, theGWorld1 gets allocated just fine (and pixBase1
- looks ok), but theGWorld2 is NULL (and pixBase2 is not valid). Both err1
- and err2 are zero. What is going on/what am I doing wrong? There is no
- mention in IM VI what a zero GWorldPtr means. I had assumed that it would
- mean that there wasn't enough memory to allocate the pixel maps, but the pixel
- maps aren't very large and I have the memory partition for the app set plenty
- large. Thanks for any help you can give me.
-
- Doug Schwarz
- Eastman Kodak Company
- schwarz@kodak.com
-
- +++++++++++++++++++++++++++
-
- >From python@world.std.com (Steven J. Bushell)
- Date: Wed, 24 Aug 1994 11:48:59 -0500
- Organization: Kodak Electronic Printing Systems, Inc.
-
- In article <schwarz-2308941607420001@150.220.61.78>, schwarz@kodak.com
- (Doug Schwarz) wrote:
- [ code deleted ]
- > In the code fragment above, theGWorld1 gets allocated just fine (and pixBase1
- > looks ok), but theGWorld2 is NULL (and pixBase2 is not valid). Both err1
- > and err2 are zero. What is going on/what am I doing wrong? There is no
- > mention in IM VI what a zero GWorldPtr means. I had assumed that it would
- > mean that there wasn't enough memory to allocate the pixel maps, but the pixel
- > maps aren't very large and I have the memory partition for the app set plenty
- > large. Thanks for any help you can give me.
- >
- > Doug Schwarz
- > Eastman Kodak Company
- > schwarz@kodak.com
-
- It's an undocumented feature of NewGWorld that it returns no error when it
- has insufficient memory to allocate the GWorld. You should ALWAYS check
- the GWorldPtr to determine if the call was successful. The only time you
- get errors back from NewGWorld is when you pass ridiculous parameters to
- it. I've never seen any other errors come back from it.
-
- Considering this, plus the fact that the first call to NewGWorld was
- successful, you can pretty safely assume that you are short on memory.
- Double-check your boundsRect, and make sure your heap isn't fragmented
- too. A quick way to confirm that it is a memory problem would be to cut
- the boundsRect in half and see if both calls succeed. If they don't,
- check to make sure your heap's okay.
-
- - Steve
-
- //////////
- //
- // Steve Bushell
- // python@world.std.com
- //
- // "It's always the quiet ones."
- //
- //////////
-
- +++++++++++++++++++++++++++
-
- >From dab@zork.tiac.net (Dana Basken)
- Date: 24 Aug 1994 16:41:23 GMT
- Organization: Rockland Software
-
- In article <python-2408941148590001@155.50.26.175>
- python@world.std.com (Steven J. Bushell) writes:
-
- > It's an undocumented feature of NewGWorld that it returns no error when it
- > has insufficient memory to allocate the GWorld. You should ALWAYS check
- > the GWorldPtr to determine if the call was successful. The only time you
- > get errors back from NewGWorld is when you pass ridiculous parameters to
- > it. I've never seen any other errors come back from it.
-
- It's odd that you have never seen any other errors return from
- NewGWorld. If and when I try to create a GWorld using NewGWorld that
- is too large to fit into memory, I get a result code of -108
- (memFullErr) every time. In my experience, I've never seen NewGWorld
- not create a GWorld and pass back noErr.
-
- I would look for some other reason in the failure of the allocation of
- your GWorld.
-
- - Dana
-
- - -
- Dana Basken dab@mote.tiac.net
- Rockland Software
-
- +++++++++++++++++++++++++++
-
- >From tg3@u.washington.edu (Thurman Gillespy III)
- Date: Wed, 24 Aug 1994 11:55:51 -0800
- Organization: Dept of Radiology, Univ of Washington
-
- In article <schwarz-2308941607420001@150.220.61.78>, schwarz@kodak.com
- (Doug Schwarz) wrote:
-
- > I am trying to create multiple offscreen graphics worlds.
- >
- > QDErr err1, err2;
- > PixMapHandle pixBase1, pixBase2;
- > GWorldPtr theGWorld1, theGWorld2;
- > CGrafPtr currentPort;
- > GDHandle currentDevice;
- > Rect boundsRect;
- >
- > GetGWorld(¤tPort, ¤tDevice);
- > err1 = NewGWorld(&theGWorld1, 32, &boundsRect, NULL, NULL, 0);
- > pixBase1 = GetGWorldPixMap(theGWorld1);
- > SetGWorld(currentPort, currentDevice);
- >
- > GetGWorld(¤tPort, ¤tDevice);
- > err2 = NewGWorld(&theGWorld2, 32, &boundsRect, NULL, NULL, 0);
- > pixBase2 = GetGWorldPixMap(theGWorld2);
- > SetGWorld(currentPort, currentDevice);
- >
- Err, you HAVE defined boundsRect further, havn't you?
- --
- Thurman Gillespy III | tg3@u.washington.edu
- Department of Radiology, SB-05 | voice (206)543-3320
- University of Washington | fax (206)543-6317
- Seattle, WA 98195 |
-
- +++++++++++++++++++++++++++
-
- >From snozer@cats.ucsc.edu (Daniel Craig Jalkut)
- Date: 24 Aug 1994 21:21:31 GMT
- Organization: University of California, Santa Cruz
-
-
- In <schwarz-2308941607420001@150.220.61.78> schwarz@kodak.com (Doug Schwarz) writes:
-
- >I am trying to create multiple offscreen graphics worlds.
-
- > QDErr err1, err2;
- > PixMapHandle pixBase1, pixBase2;
- > GWorldPtr theGWorld1, theGWorld2;
- > CGrafPtr currentPort;
- > GDHandle currentDevice;
- > Rect boundsRect;
-
- > GetGWorld(¤tPort, ¤tDevice);
- > err1 = NewGWorld(&theGWorld1, 32, &boundsRect, NULL, NULL, 0);
- > pixBase1 = GetGWorldPixMap(theGWorld1);
- > SetGWorld(currentPort, currentDevice);
-
- > GetGWorld(¤tPort, ¤tDevice);
- > err2 = NewGWorld(&theGWorld2, 32, &boundsRect, NULL, NULL, 0);
- > pixBase2 = GetGWorldPixMap(theGWorld2);
- > SetGWorld(currentPort, currentDevice);
-
-
- >In the code fragment above, theGWorld1 gets allocated just fine (and pixBase1
- >looks ok), but theGWorld2 is NULL (and pixBase2 is not valid). Both err1
- >and err2 are zero. What is going on/what am I doing wrong? There is no
- >mention in IM VI what a zero GWorldPtr means. I had assumed that it would
- >mean that there wasn't enough memory to allocate the pixel maps, but the pixel
- >maps aren't very large and I have the memory partition for the app set plenty
- >large. Thanks for any help you can give me.
-
- >Doug Schwarz
- >Eastman Kodak Company
- >schwarz@kodak.com
-
- Any GWorld references I've read have always insisted that you check
- both the return value being noErr, *and* the GworldPtr being != NULL.
- Probably you are somehow passing NewGWorld parameters that seem ok,
- and it does it's job ok, but doesn't put the results where you expect
- it to. I can't see from your example code anything that looks wrong in
- the NewGWorld calls. It is weird that you call GetGWorld and SetGWorld
- before and after your NewGWorld calls, though. I may be wrong, but I
- don't think NewGWorld does any modification to the active GrafPort or
- GDevice. You only need to Get/SaveGworld before and after you do
- any drawing to the GWorld(just like a GrafPort, in fact I've seen it
- recommended that if you use GWorlds at all your just use Get/SaveGWorld
- in *lieu* of Get/SavePort.
-
- The main problem I ran into when learning GWorlds was running out of memory,
- and it did return the proper error code. I concur with the other person
- who said that they have never had NewGWorld return noErr in reaction
- to an out of memory error. If you use GWorlds or anything else that is
- memory intensive, you will probably have to change the default heap size
- of your application from whatever compiler you use.
-
- --
- ____
- / /\ \ Daniel Craig Jalkut "All I know is that I don't know nothing,
- -/--\- snozer@cats.ucsc.edu and that's FINE" -- Operation Ivy
- X____X UNIX, coffee, politics, punk-rock, Mac, women, food, and more.
-
-
- +++++++++++++++++++++++++++
-
- >From Darrin Cardani <Darrin.Cardani@AtlantaGA.NCR.COM>
- Date: Wed, 24 Aug 1994 19:34:38 GMT
- Organization: AT&T Global Information Solutions, Atlanta
-
- >In article <33ft7j$llk@sundog.tiac.net> Dana Basken writes:
- >In article <python-2408941148590001@155.50.26.175>
- >python@world.std.com (Steven J. Bushell) writes:
- >
- >> It's an undocumented feature of NewGWorld that it returns no error when it
- >> has insufficient memory to allocate the GWorld. You should ALWAYS check
- >> the GWorldPtr to determine if the call was successful. The only time you
- >> get errors back from NewGWorld is when you pass ridiculous parameters to
- >> it. I've never seen any other errors come back from it.
- >
- >It's odd that you have never seen any other errors return from
- >NewGWorld. If and when I try to create a GWorld using NewGWorld that
- >is too large to fit into memory, I get a result code of -108
- >(memFullErr) every time. In my experience, I've never seen NewGWorld
- >not create a GWorld and pass back noErr.
-
- I too have seen the noErr, but no memory problem. Is there maybe more to
- it than those 2 factors? (Maybe, there's enough mem., but it's too fragmented
- or something wacko like that?)
-
- Darrin
-
-
-
-
-
-
-
- +++++++++++++++++++++++++++
-
- >From schwarz@kodak.com (Doug Schwarz)
- Date: Wed, 24 Aug 1994 20:26:47 GMT
- Organization: Eastman Kodak Company, Rochester, NY
-
- In article <33ft7j$llk@sundog.tiac.net>, dab@zork.tiac.net (Dana Basken) wrote:
-
- > It's odd that you have never seen any other errors return from
- > NewGWorld. If and when I try to create a GWorld using NewGWorld that
- > is too large to fit into memory, I get a result code of -108
- > (memFullErr) every time. In my experience, I've never seen NewGWorld
- > not create a GWorld and pass back noErr.
- >
- > I would look for some other reason in the failure of the allocation of
- > your GWorld.
- >
- > - Dana
-
- I wrote a small application containing little more than my original code
- fragment and I also get a result of -108 when there is not enough memory.
- It never returns a null GWorld and a zero error. So, it seems that I need
- to give a more complete description of my original problem.
-
- I am using THINK C 7.0.3 and the TCL 1.1.3. The allocation of the GWorlds
- is done in the initialization method for a class. I create two instances
- of my class and initialize them like so:
-
- SetRect(&bounds, ...);
- instance1 = new(COffscreenPixMap);
- instance1->IOffscreenPixMap(bounds);
- instance2 = new(COffscreenPixMap);
- instance2->IOffscreenPixMap(bounds);
-
- where, IOffscreenPixMap() is something like:
-
-
- class COffscreenPixMap : CObject
- {
- private:
- CGrafPtr currentPort;
- GDHandle currentDevice;
- GWorldPtr theGWorld;
-
- public:
- void IOffscreenPixMap(Rect);
- };
-
- void COffscreenPixMap::IOffscreenPixMap(Rect boundsRect)
- {
- QDErr err, qderr;
- PixMapHandle pixBase;
-
- GetGWorld(¤tPort, ¤tDevice);
- err = NewGWorld(&theGWorld, 32, &boundsRect, NULL, NULL, 0);
- qderr = QDError();
- pixBase = GetGWorldPixMap(theGWorld);
- SetGWorld(currentPort, currentDevice);
- return;
- }
-
-
- When I step through the program using the source level debugger,
- everything works fine with instance1. When I get to NewGWorld for
- instance2, I get
- err = 0, theGWorld = NULL and qderr = 0. If I purposely set the memory
- partition for the app too low, I never return from NewGWorld, but I get a
- dialog from the TCL telling me that there is not enough memory. (This I
- also do not understand). The app never really recovers from this and I
- have to enter MacsBug and do an ES. I don't really care about that right
- now, I just want to be able to allocate my second GWorld.
-
- Please note: I definitely have enough memory to allocate these two
- GWorlds. They each take a little over 1 MB and I have the memory
- partition for the app set to 23 MB (the machine has 32M). All of this
- stuff is right at the beginning of IApplication() so no other large
- objects have been created.
-
- Thanks for all the help so far! Does anybody know what is going on?
-
- Doug Schwarz
- Eastman Kodak Company
- schwarz@kodak.com
-
- +++++++++++++++++++++++++++
-
- >From Jaeger@fquest.com (Brian Stern)
- Date: 25 Aug 1994 05:25:14 GMT
- Organization: The University of Texas at Austin, Austin, Texas
-
- In article <schwarz-2408941626470001@150.220.61.78>, schwarz@kodak.com
- (Doug Schwarz) wrote:
-
- > I wrote a small application containing little more than my original code
- > fragment and I also get a result of -108 when there is not enough memory.
- > It never returns a null GWorld and a zero error. So, it seems that I need
- > to give a more complete description of my original problem.
- >
- > When I step through the program using the source level debugger,
- > everything works fine with instance1. When I get to NewGWorld for
- > instance2, I get
- > err = 0, theGWorld = NULL and qderr = 0. If I purposely set the memory
- > partition for the app too low, I never return from NewGWorld, but I get a
- > dialog from the TCL telling me that there is not enough memory. (This I
- > also do not understand). The app never really recovers from this and I
- > have to enter MacsBug and do an ES. I don't really care about that right
- > now, I just want to be able to allocate my second GWorld.
- >
- > Please note: I definitely have enough memory to allocate these two
- > GWorlds. They each take a little over 1 MB and I have the memory
- > partition for the app set to 23 MB (the machine has 32M). All of this
- > stuff is right at the beginning of IApplication() so no other large
- > objects have been created.
- >
- > Thanks for all the help so far! Does anybody know what is going on?
- >
- > Doug Schwarz
- > Eastman Kodak Company
- > schwarz@kodak.com
-
- Hi Doug,
-
- Guess what. You are successfully creating two GWorlds. That's why your
- return values are err = 0, and qderr = 0. The problem is that the
- GWorldPtr isn't going where you think it is. In TCL 1.1.3 objects are
- handles and your instance variables can move when you call a toolbox
- routine that can move memory, like NewGWorld. You have two choices. Use
- local variables when you need to pass by reference and copy the result to
- your instance variables or else lock the object using the utility routine
- 'Lock'.
-
- The problem you mention with the TCL not enough mem error msg is because
- TCL has a GrowZone proc. If it can't free up enough mem to satisfy the
- request it throws an exception. This includes a longjump out of the trap
- that was requesting memory. I think that this can screw up everything, as
- you discovered.
-
- --
- Brian Stern :-{)}
- Jaeger@fquest.com
-
- +++++++++++++++++++++++++++
-
- >From python@world.std.com (Steven J. Bushell)
- Date: Thu, 25 Aug 1994 11:44:02 -0500
- Organization: Kodak Electronic Printing Systems, Inc.
-
- In article <schwarz-2408941626470001@150.220.61.78>, schwarz@kodak.com
- (Doug Schwarz) wrote:
-
- > void COffscreenPixMap::IOffscreenPixMap(Rect boundsRect)
- > {
- > QDErr err, qderr;
- > PixMapHandle pixBase;
- >
- > GetGWorld(¤tPort, ¤tDevice);
- > err = NewGWorld(&theGWorld, 32, &boundsRect, NULL, NULL, 0);
- > qderr = QDError();
- > pixBase = GetGWorldPixMap(theGWorld);
- > SetGWorld(currentPort, currentDevice);
- > return;
- > }
- > Thanks for all the help so far! Does anybody know what is going on?
-
- Have you tried locking your object before creating the GWorld? If you
- don't, the address of 'theGWorld' can become invalid if memory moves
- around (i.e., when creating a new GWorld), and the pointer to the GWorld
- will be stored in some random place in memory. Remember, TCL 1.1.3 is
- still handle-based so you have to watch out when using addresses of
- instance vars; TCL 2.0 is pointer based so you can avoid these problems if
- you use a newer TCL.
-
- - Steve
-
- //////////
- //
- // Steve Bushell
- // python@world.std.com
- //
- // "It's always the quiet ones."
- //
- //////////
-
- +++++++++++++++++++++++++++
-
- >From schwarz@kodak.com (Doug Schwarz)
- Date: Thu, 25 Aug 1994 17:26:03 GMT
- Organization: Eastman Kodak Company, Rochester, NY
-
- In article <Jaeger-2508940027100001@slip-11-9.ots.utexas.edu>,
- Jaeger@fquest.com (Brian Stern) wrote:
-
- > Guess what. You are successfully creating two GWorlds. That's why your
- > return values are err = 0, and qderr = 0. The problem is that the
- > GWorldPtr isn't going where you think it is. In TCL 1.1.3 objects are
- > handles and your instance variables can move when you call a toolbox
- > routine that can move memory, like NewGWorld. You have two choices. Use
- > local variables when you need to pass by reference and copy the result to
- > your instance variables or else lock the object using the utility routine
- > 'Lock'.
- >
- > The problem you mention with the TCL not enough mem error msg is because
- > TCL has a GrowZone proc. If it can't free up enough mem to satisfy the
- > request it throws an exception. This includes a longjump out of the trap
- > that was requesting memory. I think that this can screw up everything, as
- > you discovered.
- >
- > --
- > Brian Stern :-{)}
- > Jaeger@fquest.com
-
-
- In article <python-2508941144020001@155.50.26.175>, python@world.std.com
- (Steven J. Bushell) wrote:
-
- > Have you tried locking your object before creating the GWorld? If you
- > don't, the address of 'theGWorld' can become invalid if memory moves
- > around (i.e., when creating a new GWorld), and the pointer to the GWorld
- > will be stored in some random place in memory. Remember, TCL 1.1.3 is
- > still handle-based so you have to watch out when using addresses of
- > instance vars; TCL 2.0 is pointer based so you can avoid these problems if
- > you use a newer TCL.
- >
- > - Steve
- >
- > // Steve Bushell
- > // python@world.std.com
-
-
-
- Yes! Brian and Steve are correct. I replaced
-
- err = NewGWorld(&theGWorld, 32, &boundsRect, NULL, NULL, 0);
-
- where theGWorld is an instance variable, with
-
- GWorldPtr tempGWorld;
- err = NewGWorld(&tempGWorld, 32, &boundsRect, NULL, NULL, 0);
- theGWorld = tempGWorld;
-
- where tempGWorld is a local variable and it works just fine. I was also able to
- make some other simplifications once *that* was working (thanks to some other
- helpful suggestions).
-
- So, THANK YOU EVERYBODY and especially Brian and Steve!
-
- Doug Schwarz
- Eastman Kodak Company
- schwarz@kodak.com
-
- ---------------------------
-
- >From partingt@fwi.uva.nl (Vincent Partington)
- Subject: Won't strange windows come in my layer?
- Date: 23 Aug 1994 11:09:43 GMT
- Organization: FWI, University of Amsterdam
-
- Hi everyone,
-
- I'm investigating putting a pointer to an object in the refCon of a windowPtr
- to call a virtual function (C++) through it. I was wondering:
- Can I be sure I'll only get events for my own windows? Can I be sure the
- refCon value doesn't contain garbage?
- I know under System 6 DA's would invade your window list but they can be
- recognized by looking at the windowKind (or something). It's it ok for my
- app to break if somebody makes an INIT that puts windows in my layer?
-
- Thanks, Vincent
- --
- appel peer banaan baksteen ||| The Fingerware Project:
- schelp zon zand rolstoel ||| Put your code snippets in your .plan!
- groen wit geel flatgebouw ||| If you want to know more
- boer postbode bouwvakker roos ||| finger partingt@gene.fwi.uva.nl
-
- +++++++++++++++++++++++++++
-
- >From Jaeger@fquest.com (Brian Stern)
- Date: 23 Aug 1994 16:44:50 GMT
- Organization: The University of Texas at Austin, Austin, Texas
-
- In article <33cldn$ncd@hermes.fwi.uva.nl>, partingt@fwi.uva.nl (Vincent
- Partington) wrote:
-
- > Hi everyone,
- >
- > I'm investigating putting a pointer to an object in the refCon of a windowPtr
- > to call a virtual function (C++) through it. I was wondering:
- > Can I be sure I'll only get events for my own windows? Can I be sure the
- > refCon value doesn't contain garbage?
- > I know under System 6 DA's would invade your window list but they can be
- > recognized by looking at the windowKind (or something). It's it ok for my
- > app to break if somebody makes an INIT that puts windows in my layer?
- >
- > Thanks, Vincent
- > --
- > appel peer banaan baksteen ||| The Fingerware Project:
- > schelp zon zand rolstoel ||| Put your code snippets in your .plan!
- > groen wit geel flatgebouw ||| If you want to know more
- > boer postbode bouwvakker roos ||| finger partingt@gene.fwi.uva.nl
-
- Vincent,
-
- You should set the WindowKind of any window when you create it; choose
- values that are not among the already defined values (> 8 I think). Then
- when you receive window events you check the windowkind first and then act
- accordingly. You can put anything you like in the refcon, including
- object references. If you do this then presumably you wouldn't do
- anything for a windowkind that your app doesn't know about.
-
- I wouldn't worry about an INIT putting windows in your layer. If I was
- writing an INIT to do such a thing I'd be sure to steal any window events
- related to that window before your app ever saw them.
-
- --
- Brian Stern :-{)}
- Jaeger@fquest.com
-
- +++++++++++++++++++++++++++
-
- >From jonasw@lysator.liu.se (Jonas Wallden)
- Date: 23 Aug 1994 21:02:05 GMT
- Organization: (none)
-
- Jaeger@fquest.com (Brian Stern) writes:
-
- >In article <33cldn$ncd@hermes.fwi.uva.nl>, partingt@fwi.uva.nl (Vincent
- >Partington) wrote:
-
- >> Hi everyone,
- >>
- >> I'm investigating putting a pointer to an object in the refCon of a windowPtr
- >> to call a virtual function (C++) through it. I was wondering:
- >> Can I be sure I'll only get events for my own windows? Can I be sure the
- >> refCon value doesn't contain garbage?
- >> I know under System 6 DA's would invade your window list but they can be
- >> recognized by looking at the windowKind (or something). It's it ok for my
- >> app to break if somebody makes an INIT that puts windows in my layer?
- >>
- >> Thanks, Vincent
- >> --
- >> appel peer banaan baksteen ||| The Fingerware Project:
- >> schelp zon zand rolstoel ||| Put your code snippets in your .plan!
- >> groen wit geel flatgebouw ||| If you want to know more
- >> boer postbode bouwvakker roos ||| finger partingt@gene.fwi.uva.nl
- >
- >Vincent,
- >
- >You should set the WindowKind of any window when you create it; choose
- >values that are not among the already defined values (> 8 I think). Then
- >when you receive window events you check the windowkind first and then act
- >accordingly. You can put anything you like in the refcon, including
- >object references. If you do this then presumably you wouldn't do
- >anything for a windowkind that your app doesn't know about.
- >
- >I wouldn't worry about an INIT putting windows in your layer. If I was
- >writing an INIT to do such a thing I'd be sure to steal any window events
- >related to that window before your app ever saw them.
- >
- >Brian Stern :-{)}
-
- A great way to extend WindowRecords is to declare your own data type with
- a WindowRecord as the first item.
-
- E.g.,
-
- struct tMyWinData {
- // This must come first!
- WindowRecord winRec;
-
- // Additional window-specific data here...
- Handle aHandle;
- Ptr aPtr;
- };
- typedef struct tMyWinData tMyWinData;
- typedef tMyWinData *tMyWinPtr;
-
- The trick now is that you can typecast any window pointer to tMyWinPtr (and
- back) and access your window-specific data fields. You might want to place
- your application's unique creator code in the WindowRecord refCon field and
- check it first to be sure you have a window that belongs to your program.
-
- I use this all the time and it is useful in many other places where the
- system gives you a pointer to an object (VBL tasks, ParamBlocks, ...) and
- you need to store extra data. No need to use any globals for this stuff!
-
- --
- `.`. Jonas Wallden `.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.
- `.`.`. Internet: jonasw@lysator.liu.se `.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.
- `.`.`.`. AppleLink: sw1369 `.`.`.`.`.`.`.`.`.`.`.`.`.`.`.
-
- +++++++++++++++++++++++++++
-
- >From benh@fdn.org (Benjamin Herrenschmidt)
- Date: Tue, 23 Aug 94 17:24:09 +0100
- Organization: (none)
-
-
- In article <33cldn$ncd@hermes.fwi.uva.nl> (comp.sys.mac.programmer), partingt@fwi.uva.nl (Vincent Partington) writes:
-
- >I'm investigating putting a pointer to an object in the refCon of a windowPtr
- >to call a virtual function (C++) through it. I was wondering:
- >Can I be sure I'll only get events for my own windows? Can I be sure the
- >refCon value doesn't contain garbage?
- >I know under System 6 DA's would invade your window list but they can be
- >recognized by looking at the windowKind (or something). It's it ok for my
- >app to break if somebody makes an INIT that puts windows in my layer?
-
- I think you should have somewhere a list of YOUR windows, so you can
- check it's one of yours before using it's refcon. Another way to do
- so is to use a custom windowKind and check for it (that's what PowerPlant
- does) but you are not protected against someone using the same windowKind
- (there is no way to register them).
-
- BenH.
-
- +++++++++++++++++++++++++++
-
- >From lsr@taligent.com (Larry Rosenstein)
- Date: Tue, 23 Aug 1994 23:04:25 GMT
- Organization: Taligent, Inc.
-
- In article <33cldn$ncd@hermes.fwi.uva.nl>, partingt@fwi.uva.nl (Vincent
- Partington) wrote:
-
- > Can I be sure I'll only get events for my own windows? Can I be sure the
- > refCon value doesn't contain garbage?
-
- No. For example, there's a program called PacerForum (a BBS app) that can
- pop up notification windows inside your application's space. It makes the
- windows look like DAs (negative windowKind) so if you handle those
- properly you should be OK.
-
- --
- Larry Rosenstein
- Taligent, Inc.
-
- lsr@taligent.com
-
- +++++++++++++++++++++++++++
-
- >From h+@nada.kth.se (Jon W{tte)
- Date: Wed, 24 Aug 1994 10:23:51 +0200
- Organization: Royal Institute of Something or other
-
- In article <33cldn$ncd@hermes.fwi.uva.nl>,
- partingt@fwi.uva.nl (Vincent Partington) wrote:
-
- >It's it ok for my
- >app to break if somebody makes an INIT that puts windows in my layer?
-
- Yes; PowerPlant, TCL and MacApp all put object pointers in the
- refCon. To be really safe, set the windowKind of windows you
- create to something >8, like 11147, and test for that first.
- Also test that the object pointer is not 0 (and if you're
- paranoid; not odd and above your heap start and below your
- stack base)
-
- Cheers,
-
- / h+
-
-
- --
- Jon W‰tte (h+@nada.kth.se), Hagagatan 1, 113 48 Stockholm, Sweden
- "Don't use the Layer Manager"
-
-
- +++++++++++++++++++++++++++
-
- >From h+@nada.kth.se (Jon W{tte)
- Date: Wed, 24 Aug 1994 23:10:45 +0200
- Organization: Royal Institute of Something or other
-
- In article <01050105.7vo9pz@tatooine.fdn.org>,
- benh@fdn.org (Benjamin Herrenschmidt) wrote:
-
- >I think you should have somewhere a list of YOUR windows, so you can
- >check it's one of yours before using it's refcon. Another way to do
- >so is to use a custom windowKind and check for it (that's what PowerPlant
- >does) but you are not protected against someone using the same windowKind
- >(there is no way to register them).
-
- No, but there is simply NO WAY that someone elses window gets
- into your window list, unless that's a DA/system window, in
- which case the windowKind will be negative. Using a separate
- list is just a lot of trouble to avoid something which won't
- happen; sort of lugging around a portable bomb shelter in case
- a meteorite would hit you...
-
- Cheers,
-
-
- / h+
-
-
- --
- Jon W‰tte (h+@nada.kth.se), Hagagatan 1, 113 48 Stockholm, Sweden
- "Don't use the Layer Manager"
-
-
- +++++++++++++++++++++++++++
-
- >From sigurasg@plusplus.is (Sigurdur Asgeirsson)
- Date: 25 Aug 1994 09:03:27 GMT
- Organization: Plusplus Inc.
-
- h+@nada.kth.se (Jon W{tte) writes:
-
- >In article <01050105.7vo9pz@tatooine.fdn.org>,
- >benh@fdn.org (Benjamin Herrenschmidt) wrote:
-
- >>I think you should have somewhere a list of YOUR windows, so you can
-
- [snip]
-
- >No, but there is simply NO WAY that someone elses window gets
- >into your window list, unless that's a DA/system window, in
- >which case the windowKind will be negative. Using a separate
- >list is just a lot of trouble to avoid something which won't
- >happen; sort of lugging around a portable bomb shelter in case
- >a meteorite would hit you...
-
- Uhm, hate to rain on your parade, but what about CTB windows? CTB
- tools are allowed to put up windows (just about anytime if I remember
- correctly), AND they use the RefCon for their own purposes, so if
- you're using the CTB beware...
-
- --
- Sigurdur Asgeirsson | "Well you know, C isn't that hard, void (*(*f[])())()
- Kambasel 26 | for instance declares f as an array of unspecified
- 109 Reykjavik, Iceland | size, of pointers to functions that return pointers to
- sigurasg@plusplus.is | functions that return void... I think"
-
- ---------------------------
-
- End of C.S.M.P. Digest
- **********************
-
-
-